package com.jxpowernode.bitcon.createBitcon;

import org.bitcoinj.core.Base58;

import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECPoint;

/**
 * @Author: Lixuewei
 * @Email:1410511702@qq.com
 * @Desc:
 * @Date: 2021/12/9 13:29
 */
public class CreateBitconAdder {

    public  String getAdder() throws UnsupportedEncodingException, NoSuchProviderException, IllegalAccessException {
        String add = "";
        try {
            //生成密钥
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
            ECGenParameterSpec spec = new ECGenParameterSpec("secp256k1");
            //指定密钥长度
            keyGen.initialize(spec);
            //生成密钥对
            KeyPair kp = keyGen.generateKeyPair();
            //获取公钥
            PublicKey pub = kp.getPublic();
            //将pub转换为椭圆曲线的公钥
            ECPublicKey epub = (ECPublicKey) pub;
            ECPoint pt = epub.getW();
            //根据x，y坐标，拼接得到非压缩格式的公钥
            String sx = adjusTo64(pt.getAffineX().toString(16).toUpperCase());
            String sy = adjusTo64(pt.getAffineY().toString(16).toUpperCase());
            String bcPub = "04" + sx + sy;
          //  String bcPub = sx + sy;
            //System.out.println(bcPub);
            //对公钥进行双重hash计算
            MessageDigest sha = MessageDigest.getInstance("SHA-256");
           byte[] s1 = sha.digest(bcPub.getBytes("UTF-8"));

            // System.out.println("sha:"+bytesToHex(s1).toUpperCase);
            MessageDigest rmd = MessageDigest.getInstance("RipeMD160", "BC");
            byte[] r1 = rmd.digest(s1);
            //在hash前加入版本号0x00
            byte[] r2 = new byte[r1.length + 1];
            r2[0] = 0x00;
            for (int i = 0; i < r1.length; i++) {
                r2[i + 1] = r1[i];
            }
            //重复两次sha256
            byte[] s2 = sha.digest(r2);
            byte[] s3 = sha.digest(s2);
            byte[] a1 = new byte[25];
            //将r2原来的值赋值给a2
            for (int i = 0; i < r2.length; i++) {
                a1[i] = r2[i];
            }
            //将被2次hash的密钥取前四位作为校验码并加入到添加过版本号的公钥后
            for (int i = 0; i < 5; i++) {
                a1[20 + i] = s3[i];
            }
            //将加过校验码的公钥进行base58加密得到地址
             add = Base58.encode(a1);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }
        return add;
    }


    static private String adjusTo64(String str) throws IllegalAccessException {
        switch (str.length()) {
            case 62:
                return "00" + str;
            case 63:
                return "0" + str;
            case 64:
                return str;
            default:
                throw new IllegalAccessException("not a vaild key :" + str);
        }
    }

}

